package com.stars.aspect;

import com.stars.common.MyReflectionUtils;
import com.stars.common.MyStrRegex;
import com.stars.common.annotation.FieldRepeatVailClass;
import com.stars.common.annotation.FieldRepeatValidator;
import com.stars.common.base.BaseConstant;
import com.stars.common.base.BaseMsg;
import com.stars.common.base.ResultMsg;
import com.stars.common.enums.SaveTypeEnum;
import com.stars.common.valid.MyException;
import com.stars.services.sysdict.SysDictAccessServices;
import io.swagger.annotations.ApiModelProperty;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.persistence.Table;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName FieldRepeatValidatorAspect
 * @Description: 提交之前，验证字段是否重
 * 1-保存的方法添加 @FieldRepeatVailClass 注解，方式添加，还是更新，
 * 2-实体参数必须放在第一位置，
 * 3-根据实体类上的@FieldRepeatValidator 拿到验证的字段，要正常的名称规则
 * @Author DJ
 * @Date 2019/11/6
 * @Version V1.0
 **/
@Aspect
@Component
public class FieldRepeatValidatorAspect {
    @Autowired
    private SysDictAccessServices sysDictAccessServicesImpl;

    @Pointcut("@annotation(fieldRepeatVailClass)")
    public void doFieldRepeatVailClass(FieldRepeatVailClass fieldRepeatVailClass) {
    }

    @Before("@annotation(fieldRepeatVailClass)")
    public void doBefore(JoinPoint point, FieldRepeatVailClass fieldRepeatVailClass) throws Throwable {
        Object[] res = point.getArgs();
        if (res == null) {
            throw new MyException("参数错误");
        }
        Object obj = res[0];
        if (fieldRepeatVailClass.saveBatch()) {
            List<Object> objList = (List) obj;
            ResultMsg resultMsg = (ResultMsg) res[1];
            StringBuilder msgStr = new StringBuilder();
            for (Object o : objList) {
                String msg = checkFileRepeat(o, fieldRepeatVailClass);
                if (StringUtils.isNotBlank(msg)) {
                    msgStr.append(msg);
                }
            }
            if (StringUtils.isBlank(msgStr)) {
                resultMsg.setSuccess(true);
            } else {
                resultMsg.setMsg("导入失败：" + msgStr.toString() + "  已经存在，不能重复添加");
                resultMsg.setHasErrors(true);
                resultMsg.setSuccess(false);
            }
        } else {
            checkFileRepeat(obj, fieldRepeatVailClass);
        }
    }

    private String checkFileRepeat(Object obj, FieldRepeatVailClass fieldRepeatVailClass) throws Exception {
        FieldRepeatValidator fieldRepeatValidator = (FieldRepeatValidator) MyReflectionUtils.getDeclaredAnnotation(obj, FieldRepeatValidator.class);
        Table table = (Table) MyReflectionUtils.getDeclaredAnnotation(obj, Table.class);
        String[] fieldList;
        if (null == fieldRepeatValidator) {
            return "";
        } else {
            fieldList = fieldRepeatValidator.field().split(BaseConstant.SPOT);
        }

        Map<String, String> params = new HashMap<>();
        StringBuilder areNameList = new StringBuilder();
        StringBuilder areList = new StringBuilder();
        for (String field : fieldList) {
            if (StringUtils.isBlank(field)) {
                continue;
            }
            String fieldVal = (String) MyReflectionUtils.getFieldValue(obj, field.trim());
            areList.append("[" + fieldVal + "]  ");
            areNameList.append("[" + boApiModelProperty(obj.getClass(), field) + "] ");
            params.put(MyStrRegex.upperCharToUnderLine(field), fieldVal);
        }
        if (SaveTypeEnum.SAVE_UPDATE.equals(fieldRepeatVailClass.saveType())) {
            params.put("id", (String) MyReflectionUtils.getFieldValue(obj, "id"));
        }
        Integer integer = sysDictAccessServicesImpl.fieldRepeatVail(table.name(), params);
        if (integer != 0) {
            String msg = areList.toString() + "";
            if (fieldRepeatVailClass.saveBatch()) {
                return msg;
            } else {
                throw new MyException(BaseMsg.SAVE_FAILURE + msg + "已经存在，不能重复添加");
            }
        } else {
            return "";
        }

    }

    /**
     * 获取bo中属性值
     *
     * @param cla
     * @return
     */
    private String boApiModelProperty(Class cla, String fieldName) {
        Field[] fields = cla.getDeclaredFields();
        ApiModelProperty apiModelProperty;
        for (Field field : fields) {
            if (field.isAnnotationPresent(ApiModelProperty.class)) {
                apiModelProperty = field.getAnnotation(ApiModelProperty.class);
                if (fieldName.equals(field.getName())) {
                    return apiModelProperty.value();
                }
            }
        }
        return "";
    }

}
